<script>

import { Brush, Close, VideoPlay, VideoPause } from '@element-plus/icons'

export default {
  data: function () {
    return {
      data: new Array(20).fill([]).map(() => new Array(20).fill(0)),
      runningStatus: false
    }
  },
  methods: {
    toogleCell: function (row, col) {
      if (!this.runningStatus) {
        this.data[row][col] = this.data[row][col] ? 0 : 1;
      }
    },
    clear: function () {
      this.data = new Array(20).fill([]).map(() => new Array(20).fill(0));
    },
    preset: function () {
      this.data[1][2] = 1;
      this.data[2][3] = 1;
      this.data[3][1] = 1;
      this.data[3][2] = 1;
      this.data[3][3] = 1;
    },
    toogleStart: function () {
      if (this.runningStatus) {
        this.runningStatus = false;
      } else {
        this.runningStatus = true;
        this.startLoop();
      }
    },
    startLoop: function () {
      if (this.runningStatus) {
        this.nextData = new Array(20).fill([]).map(() => new Array(20).fill(0));
        for (var row = 0; row < 20; row++) {
          for (var col = 0; col < 20; col++) {
            this.nextData[row][col] = this.nextState(row, col);
          }
        }
        this.data = this.nextData;
        setTimeout(() => { this.startLoop() }, 250);
      }
    },
    nextState(row, col) {
      var liveCount = 0;
      this.data[row - 1] && this.data[row - 1][col - 1] && liveCount++;
      this.data[row - 1] && this.data[row - 1][col] && liveCount++;
      this.data[row - 1] && this.data[row - 1][col + 1] && liveCount++;
      this.data[row] && this.data[row][col - 1] && liveCount++;
      this.data[row] && this.data[row][col + 1] && liveCount++;
      this.data[row + 1] && this.data[row + 1][col - 1] && liveCount++;
      this.data[row + 1] && this.data[row + 1][col] && liveCount++;
      this.data[row + 1] && this.data[row + 1][col + 1] && liveCount++;

      if (liveCount === 3) {
        return 1;
      } else if (liveCount === 2) {
        return this.data[row][col];
      }

      return 0;
    }
  },
  components: {
    Brush,
    Close,
    VideoPlay,
    VideoPause
  }
}
</script>

<template>
  <h1>Life Game</h1>
  <div class="board">
    <span v-for="(row, rowOffset) in data" >
      <div
        v-for="(col, colOffset) in row"
        :class="['cell', col && 'black']"
        @click="toogleCell(rowOffset, colOffset)"
      >
      </div>
    </span>
  </div>
  <el-row class="align-left">
    <el-col :span="2" :offset="9" class="line">
      <el-button @click="preset()" type="primary">
        <el-icon class="align-middle"><Brush /></el-icon>
        &nbsp;&nbsp;Preset
      </el-button>
    </el-col>
    <el-col :span="2" class="line">
      <el-button @click="clear()" type="warning">
        <el-icon class="align-middle"><Close /></el-icon>
        &nbsp;&nbsp;Clear
      </el-button>
    </el-col>
    <el-col :span="2" class="line">
      <el-button v-if="!runningStatus" @click="toogleStart" type="success">
        <el-icon class="align-middle"><VideoPlay /></el-icon>
        &nbsp;&nbsp;Start
      </el-button>
      <el-button v-else @click="toogleStart" type="danger">
        <el-icon class="align-middle"><VideoPause /></el-icon>
        &nbsp;&nbsp;Pause
      </el-button>
    </el-col>
  </el-row>
</template>

<style scoped>
  .board {
    margin: 20px auto;
    width: 400px;
    height: 400px;
    background-color: #FFFFFF;
  }
  .cell {
    float: left;
    margin: 0px -1px -1px 0px;
    width: 19px;
    height: 19px;
    border: 1px solid #CCCCCC;
  }
  .cell-ref {
    margin: 0px;
    width: 20px;
    height: 20px;
    display: inline-block;
    border: 1px solid #CCCCCC;
  }
  .black {
    background-color: #000000;
  }
  .line {
    padding: 10px;
    line-height: 42px;
  }
  .align-left {
    text-align: left;
  }
  .align-sub {
    vertical-align: sub;
  }
  .align-middle {
    vertical-align: middle;
  }
</style>
